home *** CD-ROM | disk | FTP | other *** search
/ Computer Select (Limited Edition) / Computer Select.iso / dobbs / v16n12 / propview.asc < prev    next >
Encoding:
Text File  |  1991-11-14  |  51.4 KB  |  1,715 lines

  1. _PROPVIEW: A FAMILY CLASS BROWSER_
  2. by Mike Klein
  3.  
  4. [LISTING ONE]
  5.  
  6. /*****************************************************************************
  7. PROGRAM: PropView (c) 1991 All rights reserved
  8. AUTHOR: Mike Klein
  9. VERSION: 1.5
  10. FILE: propview.exe
  11. REQUIREMENTS: Windows 3.x
  12. PURPOSE: Point to any window on screen, view info/properties, and send 
  13.          messages to window too.
  14. *****************************************************************************/
  15.  
  16. #define NOCOMM                                                                                    
  17.  
  18. #include <windows.h>
  19. #include <direct.h>
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23.  
  24. #include "propview.h"
  25.  
  26. static HWND     hDlgPropView;
  27. static HANDLE   hInstPropView;
  28. static HWND     hDlgActive;
  29. static HWND     hWndTarget;
  30. static HWND     hDlgChildren;
  31. static HWND     hDlgProperties;
  32. static HWND     hDlgSendMsg;
  33. static HWND     hDlgExtraData;
  34. static HWND     hDlgStyles;
  35.  
  36. static BYTE Text[100];
  37. static BOOL Capturing = FALSE;
  38. static FARPROC lpEnumWindowPropsProc;
  39. static FARPROC lpEnumChildrenProc;
  40. static BOOL ShowHex         = TRUE;
  41. static BOOL ShowScreenCoord = TRUE;
  42.  
  43. // Some internally used functions
  44. VOID PASCAL ExamineWindow(HWND);
  45. VOID PASCAL DrawIcons(VOID);
  46. VOID PASCAL OutlineWindow(HWND);
  47. VOID PASCAL UpdatePos(VOID);
  48.  
  49. /*****************************************************************************
  50.     FUNCTION: WinMain
  51.     PURPOSE : Calls initialization function, processes message loop
  52. *****************************************************************************/
  53. int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine,
  54.     int nCmdShow)
  55. {
  56.     WNDCLASS    wc;
  57.     MSG         msg;
  58.  
  59.     int ChildTabs[3];
  60.     int PropTab;
  61.  
  62.     int         hFile;
  63.     BYTE        Msg[81];
  64.     BYTE        Hex[5];
  65.     OFSTRUCT    OFstruct;
  66.  
  67.     // See if a version of Propview is already running
  68.     if(!hPrevInstance)
  69.     {
  70.         hInstPropView = hInstance;
  71.  
  72.         // Fill in window class structure with parameters that describe the
  73.         // main window.
  74.         wc.lpszClassName = (LPSTR) "PropView";
  75.         wc.lpfnWndProc   = MainWndProc;
  76.         wc.hInstance     = hInstPropView;
  77.         wc.lpszMenuName  = (LPSTR) "PropView";
  78.         wc.style         = CS_DBLCLKS;
  79.         wc.hIcon         = LoadIcon(hInstance, "PropView");
  80.         wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  81.         wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  82.         wc.cbClsExtra    = 0;
  83.         wc.cbWndExtra    = DLGWINDOWEXTRA;
  84.  
  85.         if(!RegisterClass((LPWNDCLASS) &wc))
  86.         {
  87.             return(FALSE);
  88.         }
  89.  
  90.         // Fill in window class structure with parameters that describe the
  91.         // single-listbox window.
  92.         wc.lpszClassName = (LPSTR) "SingleViewer";
  93.         wc.lpfnWndProc   = GenericViewerWndProc;
  94.         wc.hInstance     = hInstPropView;
  95.         wc.lpszMenuName  = NULL;
  96.         wc.style         = CS_DBLCLKS;
  97.         wc.hIcon         = LoadIcon(hInstance, "PropView");
  98.         wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  99.         wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  100.         wc.cbClsExtra    = 0;
  101.         wc.cbWndExtra    = DLGWINDOWEXTRA;
  102.  
  103.         if(!RegisterClass((LPWNDCLASS) &wc))
  104.         {
  105.             return(FALSE);
  106.         }
  107.  
  108.         // Fill in window class structure with parameters that describe the
  109.         // double-listbox window.
  110.         wc.lpszClassName = (LPSTR) "DoubleViewer";
  111.         wc.lpfnWndProc   = GenericViewerWndProc;
  112.         wc.hInstance     = hInstPropView;
  113.         wc.lpszMenuName  = NULL;
  114.         wc.style         = CS_DBLCLKS;
  115.         wc.hIcon         = LoadIcon(hInstance, "PropView");
  116.         wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  117.         wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  118.         wc.cbClsExtra    = 0;
  119.         wc.cbWndExtra    = DLGWINDOWEXTRA;
  120.  
  121.         if(!RegisterClass((LPWNDCLASS) &wc))
  122.         {
  123.             return(FALSE);
  124.         }
  125.  
  126.         // Fill in window class structure with parameters that describe the
  127.         // message sending window.
  128.         wc.lpszClassName = (LPSTR) "SendMsg";
  129.         wc.lpfnWndProc   = SendMsgWndProc;
  130.         wc.hInstance     = hInstPropView;
  131.         wc.lpszMenuName  = NULL;
  132.         wc.style         = CS_DBLCLKS;
  133.         wc.hIcon         = LoadIcon(hInstance, "PropView");
  134.         wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  135.         wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  136.         wc.cbClsExtra    = 0;
  137.         wc.cbWndExtra    = DLGWINDOWEXTRA;
  138.  
  139.         if(!RegisterClass((LPWNDCLASS) &wc))
  140.         {
  141.             return(FALSE);
  142.         }
  143.  
  144.         // Create the main window PropView
  145.         CreateDialog
  146.         (
  147.             hInstPropView,
  148.             "PropView",
  149.             NULL,
  150.             NULL
  151.         );
  152.  
  153.         // Make procedure instances for enum functions
  154.         if((lpEnumWindowPropsProc =
  155.             MakeProcInstance(EnumWindowPropsProc, hInstPropView)) == NULL)
  156.         {
  157.             return(FALSE);
  158.         }
  159.  
  160.         if((lpEnumChildrenProc =
  161.             MakeProcInstance(EnumChildrenProc, hInstPropView)) == NULL)
  162.         {
  163.             return(FALSE);
  164.         }
  165.  
  166.         // Create the Children window & set caption
  167.         if((hDlgChildren = CreateDialog
  168.         (
  169.             hInstPropView,
  170.             "SingleViewer",
  171.             hDlgPropView,
  172.             0L
  173.         )) == NULL)
  174.         {
  175.             return(FALSE);
  176.         }
  177.         SetWindowText(hDlgChildren, (LPSTR) "No Children");
  178.         SetDlgItemText
  179.         (
  180.             hDlgChildren,
  181.             IDC_STATIC,
  182.             (LPSTR) "Class\t\tCtrlID\thWnd\tCaption"
  183.         );
  184.  
  185.         // Create the Properties window & set caption
  186.         if((hDlgProperties = CreateDialog
  187.         (
  188.             hInstPropView,
  189.             "SingleViewer",
  190.             hDlgPropView,
  191.             0L
  192.         )) == NULL)
  193.         {
  194.             return(FALSE);
  195.         }
  196.         SetWindowText(hDlgProperties, (LPSTR) "No Properties");
  197.         SetDlgItemText(hDlgProperties, IDC_STATIC, (LPSTR) "Property\tValue");
  198.  
  199.         // Set tabs for children and properties list boxes
  200.         ChildTabs[0] = 53;
  201.         ChildTabs[1] = 82;
  202.         ChildTabs[2] = 111;
  203.         SendDlgItemMessage
  204.         (
  205.             hDlgChildren,
  206.             IDC_LISTBOX,
  207.             LB_SETTABSTOPS,
  208.             3,
  209.             (LONG) (LPINT) &ChildTabs
  210.         );
  211.  
  212.         PropTab = 50;
  213.  
  214.         SendDlgItemMessage
  215.         (
  216.             hDlgProperties,
  217.             IDC_LISTBOX,
  218.             LB_SETTABSTOPS,
  219.             1,
  220.             (LONG) (LPINT) &PropTab
  221.         );
  222.  
  223.         // Create the Data window
  224.         if((hDlgExtraData = CreateDialog
  225.         (
  226.             hInstPropView,
  227.             "DoubleViewer",
  228.             hDlgPropView,
  229.             0L
  230.         )) == NULL)
  231.         {
  232.             return(FALSE);
  233.         }
  234.  
  235.         SetWindowText(hDlgExtraData, (LPSTR) "Extra Data");
  236.  
  237.         // Create the Styles window
  238.         if((hDlgStyles = CreateDialog
  239.         (
  240.             hInstPropView,
  241.             "DoubleViewer",
  242.             hDlgPropView,
  243.             0L
  244.         )) == NULL)
  245.         {
  246.             return(FALSE);
  247.         }
  248.  
  249.         SetWindowText(hDlgStyles, (LPSTR) "Styles");
  250.  
  251.         // Create the SendMsg window
  252.         if((hDlgSendMsg = CreateDialog
  253.         (
  254.             hInstPropView,
  255.             "SendMsg",
  256.             hDlgPropView,
  257.             0L
  258.         )) == NULL)
  259.         {
  260.             return(FALSE);
  261.         }
  262.  
  263.         // Fill the msgs combobox in SendMsg dialog
  264.         hFile = OpenFile("wm.msg", (LPOFSTRUCT) &OFstruct, OF_READ);
  265.         if(hFile != -1)
  266.         {
  267.             FILE *fp = fdopen(hFile, "r");
  268.  
  269.             while(fscanf(fp,"%22s%4s", Msg, Hex) != EOF )
  270.             {
  271.                 if(Msg[0] != 'W')
  272.                 {
  273.                     break;
  274.                 }
  275.                 wsprintf((LPSTR) Text, "%-35.35s %s", (LPSTR) &Msg[3], (LPSTR) Hex);
  276.                 SendDlgItemMessage
  277.                 (
  278.                     hDlgSendMsg,
  279.                     IDC_MESSAGES,
  280.                     CB_ADDSTRING,
  281.                     0,
  282.                     (LONG) (LPSTR) Text
  283.                 );
  284.             }
  285.             fclose(fp);
  286.         }
  287.  
  288.         // Check some radiobutton defaults
  289.         CheckRadioButton(hDlgPropView, IDC_HEX, IDC_DEC, IDC_HEX);
  290.         CheckRadioButton(hDlgPropView, IDC_SCREEN, IDC_DIALOG, IDC_SCREEN);
  291.     }
  292.     else
  293.     {
  294.         // If there was another instance of PropView running, then switch to
  295.         // it by finding any window of class = "PropView". Then, if it's an
  296.         // icon, open the window, otherwise just make it active.
  297.         if(hDlgPropView = FindWindow("PropView", NULL))
  298.         {
  299.             if(IsIconic(hDlgPropView))
  300.             {
  301.                 ShowWindow(hDlgPropView, SW_SHOWNORMAL);
  302.             }
  303.  
  304.             SetActiveWindow(hDlgPropView);
  305.         }
  306.         return(FALSE);
  307.     }
  308.  
  309.     // Acquire and dispatch messages until a WM_QUIT message is received.
  310.     // The window handle hDlgActive points to the currently active window,
  311.     // and is used to identify and process keystrokes going to any modeless
  312.     // dialog box.
  313.     while(GetMessage((LPMSG) &msg, NULL, NULL, NULL))
  314.     {
  315.         if(hDlgActive != NULL)
  316.         {
  317.             if(!IsDialogMessage(hDlgActive, (LPMSG) &msg))
  318.             {
  319.                 TranslateMessage((LPMSG) &msg);
  320.                 DispatchMessage((LPMSG) &msg);
  321.             }
  322.         }
  323.         else
  324.         {
  325.             TranslateMessage((LPMSG) &msg);
  326.             DispatchMessage((LPMSG) &msg);
  327.         }
  328.     }
  329.     FreeProcInstance(lpEnumWindowPropsProc);
  330.     FreeProcInstance(lpEnumChildrenProc);
  331. }
  332.  
  333. /*****************************************************************************
  334.     FUNCTION: MainWndProc
  335.     PURPOSE : Processes messages for PropView dialog box
  336. *****************************************************************************/
  337. LONG FAR PASCAL MainWndProc(HWND hWnd, unsigned wMsg, WORD wParam, LONG lParam)
  338. {
  339.     HWND    hWndTemp;
  340.     POINT   Point;
  341.     FARPROC lpProc;
  342.  
  343.     // Switch stmt for acting on msgs
  344.     switch(wMsg)
  345.     {
  346.         case WM_CREATE :
  347.             hDlgPropView = hWnd;
  348.             break;
  349.         case WM_MOUSEMOVE :
  350.             // Check to see if we're capturing or not
  351.  
  352.             if(!Capturing)
  353.             {
  354.                 return(DefDlgProc(hWnd, wMsg, wParam, lParam));
  355.             }
  356.  
  357.             // Find out the window to query. Abort if same as last hWnd
  358.             GetCursorPos((LPPOINT) &Point);
  359.             if((hWndTemp = WindowFromPoint(Point)) == NULL)
  360.             {
  361.                 break;
  362.             }
  363.  
  364.             // Screen out if same window
  365.             if
  366.             (
  367.                 (hWndTemp != hWndTarget) &&
  368.                 (hWndTemp != hDlgPropView) &&
  369.                 (GetParent(hWndTemp) != hDlgPropView)
  370.             )
  371.             {
  372.                 ExamineWindow(hWndTemp);
  373.             }
  374.             UpdatePos();
  375.             break;
  376.         case WM_LBUTTONDOWN :
  377.         case WM_MBUTTONDOWN :
  378.         case WM_RBUTTONDOWN :
  379.  
  380.             // Any mouse button press cancels capture mode
  381.             if(Capturing)
  382.             {
  383.                 Capturing = FALSE;
  384.                 ReleaseCapture();
  385.             }
  386.             break;
  387.         case WM_COMMAND :
  388.             switch(wParam)
  389.             {
  390.                 case IDOK     :
  391.                 case IDCANCEL :
  392.                     SendMessage(hWnd, WM_CLOSE, 0, 0L);
  393.                     break;
  394.                 case IDC_HEX :
  395.                     ShowHex = TRUE;
  396.                     ExamineWindow(hWndTarget);
  397.                     UpdatePos();
  398.                     return(0L);
  399.                 case IDC_DEC :
  400.                     ShowHex = FALSE;
  401.                     ExamineWindow(hWndTarget);
  402.                     UpdatePos();
  403.                     return(0L);
  404.                 case IDC_SCREEN :
  405.                     ShowScreenCoord = TRUE;
  406.                     ExamineWindow(hWndTarget);
  407.                     UpdatePos();
  408.                     return(0L);
  409.                 case IDC_DIALOG :
  410.                     ShowScreenCoord = FALSE;
  411.                     ExamineWindow(hWndTarget);
  412.                     UpdatePos();
  413.                     return(0L);
  414.                 case IDC_SPY :
  415.  
  416.                     // Run a copy of Spy
  417.                     WinExec("spy", SW_SHOWNORMAL);
  418.                     return(0L);
  419.                 case IDC_CHILDREN :
  420.  
  421.                     // Show/hide the "children" window
  422.                     if(IsWindowVisible(hDlgChildren))
  423.                     {
  424.                         ShowWindow(hDlgChildren, SW_HIDE);
  425.                     }
  426.                     else
  427.                     {
  428.                         ShowWindow(hDlgChildren, SW_SHOWNORMAL);
  429.                     }
  430.                     return(0L);
  431.                 case IDC_SENDMSG :
  432.  
  433.                     // Show/hide the "SendMsg" dialog
  434.                     if(IsWindowVisible(hDlgSendMsg))
  435.                     {
  436.                         ShowWindow(hDlgSendMsg, SW_HIDE);
  437.                     }
  438.                     else
  439.                     {
  440.                         ShowWindow(hDlgSendMsg, SW_SHOWNORMAL);
  441.                     }
  442.                     return(0L);
  443.                 case IDC_DATA :
  444.  
  445.                     // Show/hide the window/class data dialog
  446.                     if(IsWindowVisible(hDlgExtraData))
  447.                     {
  448.                         ShowWindow(hDlgExtraData, SW_HIDE);
  449.                     }
  450.                     else
  451.                     {
  452.                         ShowWindow(hDlgExtraData, SW_SHOWNORMAL);
  453.                     }
  454.                     return(0L);
  455.                 case IDC_STYLES :
  456.  
  457.                     // Show/hide the window/class data dialog
  458.                     if(IsWindowVisible(hDlgStyles))
  459.                     {
  460.                         ShowWindow(hDlgStyles, SW_HIDE);
  461.                     }
  462.                     else
  463.                     {
  464.                         ShowWindow(hDlgStyles, SW_SHOWNORMAL);
  465.                     }
  466.                     return(0L);
  467.                 case IDC_PROPERTIES :
  468.  
  469.                     // Show/hide the window properties dialog
  470.                     if(IsWindowVisible(hDlgProperties))
  471.                     {
  472.                         ShowWindow(hDlgProperties, SW_HIDE);
  473.                     }
  474.                     else
  475.                     {
  476.                         ShowWindow(hDlgProperties, SW_SHOWNORMAL);
  477.                     }
  478.                     return(0L);
  479.                 case IDM_ABOUT :
  480.  
  481.                     // Bring up the modal About dialog box
  482.                     lpProc = MakeProcInstance(About, hInstPropView);
  483.                     DialogBox(hInstPropView, "About", hWnd, lpProc);
  484.                     FreeProcInstance(lpProc);
  485.                     return(0L);
  486.                 case IDM_EXIT :
  487.                     SendMessage(hWnd, WM_CLOSE, 0, 0L);
  488.                     return(0L);
  489.                 case IDM_GO :
  490.                     Capturing = TRUE;
  491.                     SetCapture(hWnd);
  492.                     return(0L);
  493.                 default :
  494.                     break;
  495.             }
  496.             break;
  497.         case WM_PAINT :
  498.             if(hWndTarget != NULL)
  499.             {
  500.                 DrawIcons();
  501.  
  502.                 // Validate areas we just painted so WM_PAINT doesn't
  503.                 ValidateRect(GetDlgItem(hDlgPropView, IDC_HWNDICON), NULL);
  504.                 ValidateRect(GetDlgItem(hDlgPropView, IDC_PARENTICON), NULL);
  505.             }
  506.             break;
  507.         case WM_CLOSE                :
  508.             DestroyWindow(hWnd);
  509.             return(0L);
  510.         case WM_ACTIVATE             :
  511.             hDlgActive = (wParam == NULL) ? NULL : hWnd;
  512.             break;
  513.         case WM_DESTROY              :
  514.             PostQuitMessage(0);
  515.             return(0L);
  516.         default                      :
  517.             break;
  518.     }
  519.     return(DefDlgProc(hWnd, wMsg, wParam, lParam));
  520. }
  521.  
  522. /*****************************************************************************
  523.     FUNCTION: GenericViewerWndProc
  524.     PURPOSE : Processes messages for generic listbox display window
  525. *****************************************************************************/
  526. LONG FAR PASCAL GenericViewerWndProc(HWND hWnd, unsigned wMsg, WORD wParam, LONG lParam)
  527. {
  528.     BYTE Entry[50];
  529.     BYTE *ptr;
  530.     HWND hWndTemp;
  531.     int Index;
  532.     // Switch stmt for acting on msgs
  533.     switch(wMsg)
  534.     {
  535.         case WM_COMMAND :
  536.             switch(wParam)
  537.             {
  538.                 case IDC_LISTBOX :
  539.                     if(HIWORD(lParam) == LBN_DBLCLK)
  540.                     {
  541.                         // Get index of entry in listbox clicked on
  542.                         if((Index = (int) SendDlgItemMessage
  543.                         (
  544.                             hWnd,
  545.                             IDC_LISTBOX,
  546.                             LB_GETCURSEL,
  547.                             0,
  548.                             0L
  549.                         )) == LB_ERR)
  550.                         {
  551.                             break;
  552.                         }
  553.                         // Get entry text
  554.                         SendDlgItemMessage
  555.                         (
  556.                             hWnd,
  557.                             IDC_LISTBOX,
  558.                             LB_GETTEXT,
  559.                             Index,
  560.                             (LONG) (LPSTR) Entry
  561.                         );
  562.                         if(hDlgChildren == hWnd)
  563.                         {
  564.                             if(Entry[0] == '\"')
  565.                             {
  566.                                 // This is when parent entry of ".." was
  567.                                 // selected
  568.                                 ExamineWindow(GetParent(hWndTarget));
  569.                             }
  570.                             else
  571.                             {
  572.                                 // Pull out the hWnd field of the child
  573.                                 // window we want to examine.
  574.                                 if(ptr = strrchr(Entry, '\t'))
  575.                                 {
  576.                                     if(*(ptr + 1) == '\"')
  577.                                     {
  578.                                         while(--ptr)
  579.                                         {
  580.                                             if(*ptr == '\t')
  581.                                             {
  582.                                                 break;
  583.                                             }
  584.                                         }
  585.                                     }
  586.                                     else
  587.                                     {
  588.                                         ++ptr;
  589.                                     }
  590.                                     if(ShowHex)
  591.                                     {
  592.                                         sscanf(ptr, "%x", &hWndTemp);
  593.                                     }
  594.                                     else
  595.                                     {
  596.                                         sscanf(ptr, "%d", &hWndTemp);
  597.                                     }
  598.                                     ExamineWindow(hWndTemp);
  599.                                 }
  600.                             }
  601.                         }
  602.                     }
  603.                     return(0L);
  604.                 default :
  605.                     break;
  606.             }
  607.             break;
  608.         case WM_CLOSE :
  609.             if(IsWindowVisible(hWnd))
  610.             {
  611.                 ShowWindow(hWnd, SW_HIDE);
  612.             }
  613.             else
  614.             {
  615.                 ShowWindow(hWnd, SW_SHOWNORMAL);
  616.             }
  617.             return(0L);
  618.         case WM_SIZE :
  619.             if(wParam != SIZEICONIC)
  620.             {
  621.                 if
  622.                 (
  623.                     hWnd == hDlgChildren ||
  624.                     hWnd == hDlgProperties
  625.                 )
  626.                 {
  627.                     // For SingleViewer dialogs...
  628.                     // Resize the static text ctrl & list box ctrl so
  629.                     // that they fill the size of the resized dialog
  630.                     if(GetDlgItem(hWnd, IDC_STATIC))
  631.                     {
  632.                         MoveWindow
  633.                         (
  634.                             GetDlgItem(hWnd, IDC_STATIC),
  635.                             0,
  636.                             0,
  637.                             LOWORD(lParam),
  638.                             12,
  639.                             TRUE
  640.                         );
  641.                     }
  642.                     if(GetDlgItem(hWnd, IDC_LISTBOX))
  643.                     {
  644.                         MoveWindow
  645.                         (
  646.                             GetDlgItem(hWnd, IDC_LISTBOX),
  647.                             0,
  648.                             12,
  649.                             LOWORD(lParam),
  650.                             HIWORD(lParam) - 12,
  651.                             TRUE
  652.                         );
  653.                     }
  654.                     InvalidateRect(GetDlgItem(hWnd, IDC_STATIC), NULL, TRUE);
  655.                 }
  656.                 else
  657.                 {
  658.                     WORD Width  = LOWORD(lParam);
  659.                     WORD Height = HIWORD(lParam);
  660.                     // For DoubleViewer dialogs...
  661.                     // Resize both of the static text ctrls & list box
  662.                     // ctrls so that they fill the size of the resized dialog.
  663.                     if(GetDlgItem(hWnd, IDC_WNDTEXT))
  664.                     {
  665.                         MoveWindow
  666.                         (
  667.                             GetDlgItem(hWnd, IDC_WNDTEXT),
  668.                             4,
  669.                             4,
  670.                             Width / 2 - 8,
  671.                             12,
  672.                             TRUE
  673.                         );
  674.                     }
  675.                     if(GetDlgItem(hWnd, IDC_CLSTEXT))
  676.                     {
  677.                         MoveWindow
  678.                         (
  679.                             GetDlgItem(hWnd, IDC_CLSTEXT),
  680.                             Width / 2 + 2,
  681.                             4,
  682.                             Width / 2 - 8,
  683.                             12,
  684.                             TRUE
  685.                         );
  686.                     }
  687.                     if(GetDlgItem(hWnd, IDC_WNDLIST))
  688.                     {
  689.                         MoveWindow
  690.                         (
  691.                             GetDlgItem(hWnd, IDC_WNDLIST),
  692.                             4,
  693.                             19,
  694.                             Width / 2 - 8,
  695.                             Height - (18 + 4),
  696.                             TRUE
  697.                         );
  698.                     }
  699.                     if(GetDlgItem(hWnd, IDC_CLSLIST))
  700.                     {
  701.                         MoveWindow
  702.                         (
  703.                             GetDlgItem(hWnd, IDC_CLSLIST),
  704.                             Width / 2 + 2,
  705.                             19,
  706.                             Width / 2 - 8,
  707.                             Height - (18 + 4),
  708.                             TRUE
  709.                         );
  710.                     }
  711.                     InvalidateRect(GetDlgItem(hWnd, IDC_WNDTEXT), NULL, TRUE);
  712.                     InvalidateRect(GetDlgItem(hWnd, IDC_CLSTEXT), NULL, TRUE);
  713.                 }
  714.             }
  715.             break;
  716.         case WM_ACTIVATE :
  717.             hDlgActive = (wParam == NULL) ? NULL : hWnd;
  718.             break;
  719.         default :
  720.             break;
  721.     }
  722.     return(DefDlgProc(hWnd, wMsg, wParam, lParam));
  723. }
  724.  
  725. /*****************************************************************************
  726.     FUNCTION: SendMsgWndProc
  727.     PURPOSE : Processes messages for message sending dialog
  728. *****************************************************************************/
  729. LONG FAR PASCAL SendMsgWndProc(HWND hWnd, unsigned wMsg, WORD wParam, LONG lParam)
  730. {
  731.     BYTE hWndText[7];
  732.     BYTE MsgText[50];
  733.     BYTE Msg[81];
  734.     BYTE wParamText[5];
  735.     BYTE lParamText[10];
  736.     // Switch stmt for acting on msgs
  737.     switch(wMsg)
  738.     {
  739.         case WM_COMMAND :
  740.             switch(wParam)
  741.             {
  742.                 case IDOK :
  743.                     SendMessage(hWnd, WM_CLOSE, 0, 0L);
  744.                     return(0L);
  745.                 case IDC_SEND :
  746.                     // Send message to target window
  747.                     GetDlgItemText
  748.                     (
  749.                         hWnd,
  750.                         IDC_HWNDTOSEND,
  751.                         (LPSTR) hWndText,
  752.                         sizeof(hWndText)
  753.                     );
  754.                     GetDlgItemText
  755.                     (
  756.                         hWnd,
  757.                         IDC_MESSAGES,
  758.                         (LPSTR) MsgText,
  759.                         sizeof(MsgText)
  760.                     );
  761.                     GetDlgItemText
  762.                     (
  763.                         hWnd,
  764.                         IDC_WPARAM,
  765.                         (LPSTR) wParamText,
  766.                         sizeof(wParamText)
  767.                     );
  768.                     GetDlgItemText
  769.                     (
  770.                         hWnd,
  771.                         IDC_LPARAM,
  772.                         (LPSTR) lParamText,
  773.                         sizeof(lParamText)
  774.                     );
  775.                     // Check for parms not filled in or null window handle
  776.                     if
  777.                     (
  778.                         hWndText[0] == '\0' ||
  779.                         MsgText[0] == '\0' ||
  780.                         wParamText[0] == '\0' ||
  781.                         lParamText[0] == '\0' ||
  782.                         !IsWindow(hWndTarget)
  783.                     )
  784.                     {
  785.                         return(0L);;
  786.                     }
  787.  
  788.                     lstrcpy((LPSTR) Msg, (LPSTR) &MsgText[36]);
  789.                     if(ShowHex)
  790.                     {
  791.                         hWnd    = (HWND) strtol(hWndText, NULL, 16);
  792.                         wMsg    = (WORD) strtol(Msg, NULL, 16);
  793.                         wParam  = (WORD) strtol(wParamText, NULL, 16);
  794.                         lParam  = (DWORD) strtol(lParamText, NULL, 16);
  795.                     }
  796.                     else
  797.                     {
  798.                         hWnd    = (HWND) strtol(hWndText, NULL, 10);
  799.                         wMsg    = (WORD) strtol(Msg, NULL, 10);
  800.                         wParam  = (WORD) strtol(wParamText, NULL, 10);
  801.                         lParam  = (DWORD) strtol(lParamText, NULL, 10);
  802.                     }
  803.                     if(PostMessage(hWnd, wMsg, wParam, lParam) == FALSE)
  804.                     {
  805.                         MessageBeep(0);
  806.                         MessageBox
  807.                         (
  808.                             hDlgSendMsg,
  809.                             "PostMessage() failed",
  810.                             "ERROR",
  811.                             MB_ICONEXCLAMATION | MB_OK
  812.                         );
  813.                     }
  814.                     SetActiveWindow(hDlgSendMsg);
  815.                     return(0L);
  816.                 default :
  817.                     break;
  818.             }
  819.             break;
  820.         case WM_CLOSE :
  821.             if(IsWindowVisible(hWnd))
  822.             {
  823.                 ShowWindow(hWnd, SW_HIDE);
  824.             }
  825.             else
  826.             {
  827.                 ShowWindow(hWnd, SW_SHOWNORMAL);
  828.             }
  829.             return(0L);
  830.         case WM_ACTIVATE :
  831.             hDlgActive = (wParam == NULL) ? NULL : hWnd;
  832.             break;
  833.         default :
  834.             break;
  835.     }
  836.     return(DefDlgProc(hWnd, wMsg, wParam, lParam));
  837. }
  838.  
  839. /*****************************************************************************
  840.     FUNCTION: UpdatePos
  841.     PURPOSE : Updates cursor information in dialog
  842. *****************************************************************************/
  843. VOID PASCAL UpdatePos(VOID)
  844. {
  845.     POINT   Point;
  846.     POINT   Client;
  847.     if(hWndTarget == NULL)
  848.     {
  849.         return;
  850.     }
  851.     // Get some cursor information
  852.     GetCursorPos((LPPOINT) &Point);
  853.     if(ShowScreenCoord == FALSE)
  854.     {
  855.         LONG Units = GetDialogBaseUnits();
  856.         WORD Xamt = LOWORD(Units);
  857.         WORD Yamt = HIWORD(Units);
  858.         Point.x = (Point.x * 4 ) / Xamt;
  859.         Point.y = (Point.y * 4 ) / Yamt;
  860.     }
  861.     if((hWndTarget != NULL) && (GetParent(hWndTarget) != NULL))
  862.     {
  863.         Client.x = Point.x;
  864.         Client.y = Point.y;
  865.         ScreenToClient(hWndTarget, (LPPOINT) &Client);
  866.     }
  867.     else
  868.     {
  869.         Client.x = 0;
  870.         Client.y = 0;
  871.     }
  872.     if(ShowHex)
  873.     {
  874.         wsprintf
  875.         (
  876.             (LPSTR) Text,
  877.             "Cursor = (0x%04x, 0x%04x), (0x%04x, 0x%04x)",
  878.             Point.x,
  879.             Point.y,
  880.             Client.x,
  881.             Client.y
  882.         );
  883.     }
  884.     else
  885.     {
  886.         wsprintf
  887.         (
  888.             (LPSTR) Text,
  889.             "Cursor = (%d, %d), (%d, %d)",
  890.             Point.x,
  891.             Point.y,
  892.             Client.x,
  893.             Client.y
  894.         );
  895.     }
  896.     SetDlgItemText(hDlgPropView, IDC_POS, (LPSTR) Text);
  897. }
  898.  
  899. /*****************************************************************************
  900.     FUNCTION: ExamineWindow
  901.     PURPOSE : Shows info on selected window (ie. children, parent, properties)
  902. *****************************************************************************/
  903. VOID PASCAL ExamineWindow(HWND hWnd)
  904. {
  905.     #define NUMCLASSSTYLES  11
  906.     #define NUMWNDSTYLES    29
  907.     HWND    hWndParent;
  908.     BYTE    ModuleFileName[30];
  909.     BYTE    ClassName[30];
  910.     BYTE    hWndText[7];
  911.     RECT    Rect;
  912.     int     i;
  913.     HANDLE  hInst;
  914.     LONG    WndStyle;
  915.     WORD    ClassStyle;
  916.     WORD    WndExtraData;
  917.     WORD    ClsExtraData;
  918.     static struct
  919.     {
  920.         WORD    Style;
  921.         LPSTR   Text;
  922.     }
  923.     ClassStyles[NUMCLASSSTYLES] =
  924.     {
  925.         {CS_BYTEALIGNCLIENT,    "CS_BYTEALIGNCLIENT"},
  926.         {CS_BYTEALIGNWINDOW,    "CS_BYTEALIGNWINDOW"},
  927.         {CS_CLASSDC,            "CS_CLASSDC"},
  928.         {CS_DBLCLKS,            "CS_DBLCLKS"},
  929.         {CS_GLOBALCLASS,        "CS_GLOBALCLASS"},
  930.         {CS_HREDRAW,            "CS_HREDRAW"},
  931.         {CS_NOCLOSE,            "CS_NOCLOSE"},
  932.         {CS_OWNDC,              "CS_OWNDC"},
  933.         {CS_PARENTDC,           "CS_PARENTDC"},
  934.         {CS_SAVEBITS,           "CS_SAVEBITS"},
  935.         {CS_VREDRAW,            "CS_VREDRAW"}
  936.     };
  937.     static struct
  938.     {
  939.         LONG    Style;
  940.         LPSTR   Text;
  941.     }
  942.     WndStyles[NUMWNDSTYLES] =
  943.     {
  944.         {WS_POPUP,              "WS_POPUP"},
  945.         {WS_OVERLAPPED,         "WS_OVERLAPPED"},
  946.         {WS_CHILD,              "WS_CHILD"},
  947.         {WS_MINIMIZE,           "WS_MINIMIZE"},
  948.         {WS_VISIBLE,            "WS_VISIBLE"},
  949.         {WS_DISABLED,           "WS_DISABLED"},
  950.         {WS_CLIPSIBLINGS,       "WS_CLIPSIBLINGS"},
  951.         {WS_CLIPCHILDREN,       "WS_CLIPCHILDREN"},
  952.         {WS_MAXIMIZE,           "WS_MAXIMIZE"},
  953.         {WS_CAPTION,            "WS_CAPTION"},
  954.         {WS_BORDER,             "WS_BORDER"},
  955.         {WS_DLGFRAME,           "WS_DLGFRAME"},
  956.         {WS_VSCROLL,            "WS_VSCROLL"},
  957.         {WS_HSCROLL,            "WS_HSCROLL"},
  958.         {WS_SYSMENU,            "WS_SYSMENU"},
  959.         {WS_THICKFRAME,         "WS_THICKFRAME"},
  960.         {WS_GROUP,              "WS_GROUP"},
  961.         {WS_TABSTOP,            "WS_TABSTOP"},
  962.         {WS_MINIMIZEBOX,        "WS_MINIMIZEBOX"},
  963.         {WS_MAXIMIZEBOX,        "WS_MAXIMIZEBOX"},
  964.         {WS_EX_DLGMODALFRAME,   "WS_EX_DLGMODALFRAME"},
  965.         {WS_EX_NOPARENTNOTIFY,  "WS_EX_NOPARENTNOTIFY"}
  966.     };
  967.     // Check for NULL hWnd
  968.     if((hWnd == NULL) || !IsWindow(hWnd))
  969.     {
  970.         return;
  971.     }
  972.     // We have a new target window
  973.     hWndTarget = hWnd;
  974.  
  975.     // DRAW ICONS
  976.     DrawIcons();
  977.  
  978.     // Turn on outline of target window
  979.     OutlineWindow(hWndTarget);
  980.  
  981.     // Update the hWnd in the SendMsg dialog
  982.     if(ShowHex)
  983.     {
  984.         wsprintf(hWndText, "0x%04x", hWndTarget);
  985.     }   
  986.     else
  987.     {
  988.         wsprintf(hWndText, "%d", hWndTarget);
  989.     }   
  990.     SetDlgItemText(hDlgSendMsg, IDC_HWNDTOSEND, (LPSTR) hWndText);
  991.  
  992.     // Display different window stats
  993.     GetClassName(hWnd, (LPSTR) ClassName, sizeof(ClassName));
  994.     if(ShowHex)
  995.     {
  996.         wsprintf
  997.         (
  998.             (LPSTR) Text,
  999.             "= 0x%04x (0x%04x), %s",
  1000.             hWnd,
  1001.             GetDlgCtrlID(hWnd),
  1002.             (LPSTR) ClassName
  1003.         );
  1004.     }
  1005.     else
  1006.     {
  1007.         wsprintf
  1008.         (
  1009.             (LPSTR) Text,
  1010.             "= %d (%d), %s",
  1011.             hWnd,
  1012.             GetDlgCtrlID(hWnd),
  1013.             (LPSTR) ClassName
  1014.         );
  1015.     }
  1016.     SetDlgItemText(hDlgPropView, IDC_HWND, (LPSTR) Text);
  1017.     if(!GetWindowText(hWnd, (LPSTR) Text, sizeof(Text)))
  1018.     {
  1019.         Text[0] = '\0';
  1020.     }
  1021.     SetDlgItemText(hDlgPropView, IDC_CAPTION, (LPSTR) Text);
  1022.     if((hWndParent = GetParent(hWnd)) != NULL)
  1023.     {
  1024.         GetClassName(hWndParent, (LPSTR) ClassName, sizeof(ClassName));
  1025.         if(ShowHex)
  1026.         {
  1027.             wsprintf
  1028.             (
  1029.                 (LPSTR) Text,
  1030.                 "= 0x%04x (0x%04x), %s",
  1031.                 hWndParent,
  1032.                 GetDlgCtrlID(hWndParent),
  1033.                 (LPSTR) ClassName
  1034.             );
  1035.         }
  1036.         else
  1037.         {
  1038.             wsprintf
  1039.             (
  1040.                 (LPSTR) Text,
  1041.                 "= %d (%d), %s",
  1042.                 hWndParent,
  1043.                 GetDlgCtrlID(hWndParent),
  1044.                 (LPSTR) ClassName
  1045.             );
  1046.         }
  1047.         SetDlgItemText(hDlgPropView, IDC_HWNDPARENT, (LPSTR) Text);
  1048.         if(!GetWindowText(hWndParent, (LPSTR) Text, sizeof(Text)))
  1049.         {
  1050.             Text[0] = '\0';
  1051.         }
  1052.         SetDlgItemText(hDlgPropView, IDC_PARENTCAPTION, (LPSTR) Text);
  1053.     }
  1054.     else
  1055.     {
  1056.         SetDlgItemText(hDlgPropView, IDC_HWNDPARENT, (LPSTR) "=");
  1057.         SetDlgItemText(hDlgPropView, IDC_PARENTCAPTION, (LPSTR) "");
  1058.     }
  1059.  
  1060.     // Get and display INSTANCE information
  1061.     hInst = GetWindowWord(hWnd, GWW_HINSTANCE);
  1062.     GetModuleFileName(hInst, (LPSTR) ModuleFileName, sizeof(ModuleFileName));
  1063.     if(ShowHex)
  1064.     {
  1065.         wsprintf
  1066.         (
  1067.             (LPSTR) Text,
  1068.             "hInst = 0x%04x, %s",
  1069.             hInst,
  1070.             (LPSTR) ModuleFileName
  1071.         );
  1072.     }
  1073.     else
  1074.     {
  1075.         wsprintf
  1076.         (
  1077.             (LPSTR) Text,
  1078.             "hInst = %d, %s",
  1079.             hInst,
  1080.             (LPSTR) ModuleFileName
  1081.         );
  1082.     }
  1083.     SetDlgItemText(hDlgPropView, IDC_HINST, (LPSTR) Text);
  1084.  
  1085.     // Get & display RECT of window
  1086.     GetWindowRect(hWnd, (LPRECT) &Rect);
  1087.     if(ShowScreenCoord == FALSE)
  1088.     {
  1089.         LONG Units = GetDialogBaseUnits();
  1090.         WORD Xamt = LOWORD(Units);
  1091.         WORD Yamt = HIWORD(Units);
  1092.         Rect.left   = (Rect.left * Xamt) / 4;
  1093.         Rect.right  = (Rect.right * Xamt) / 4;
  1094.         Rect.top    = (Rect.top * Yamt) / 4;
  1095.         Rect.bottom = (Rect.bottom * Yamt) / 4;
  1096.     }
  1097.     if(ShowHex)
  1098.     {
  1099.         wsprintf
  1100.         (
  1101.             (LPSTR) Text,
  1102.             "Rect = (0x%04x, 0x%04x)-(0x%04x, 0x%04x)",
  1103.             Rect.left,
  1104.             Rect.top,
  1105.             Rect.right,
  1106.             Rect.bottom
  1107.         );
  1108.     }
  1109.     else
  1110.     {
  1111.         wsprintf
  1112.         (
  1113.             (LPSTR) Text,
  1114.             "Rect = (%d, %d)-(%d, %d)",
  1115.             Rect.left,
  1116.             Rect.top,
  1117.             Rect.right,
  1118.             Rect.bottom
  1119.         );
  1120.     }
  1121.     SetDlgItemText(hDlgPropView, IDC_RECT, (LPSTR) Text);
  1122.  
  1123.     // Get & display CHILDREN & PROPERTY information
  1124.     SendDlgItemMessage(hDlgChildren, IDC_LISTBOX, WM_SETREDRAW, 0, 0L);
  1125.     SendDlgItemMessage(hDlgProperties, IDC_LISTBOX, WM_SETREDRAW, 0, 0L);
  1126.     SendDlgItemMessage(hDlgProperties, IDC_LISTBOX, LB_RESETCONTENT, 0, 0L);
  1127.     SendDlgItemMessage(hDlgChildren, IDC_LISTBOX, LB_RESETCONTENT, 0, 0L);
  1128.     EnumChildWindows(hWndTarget, lpEnumChildrenProc, NULL);
  1129.     if
  1130.     (
  1131.         !(i = (int) SendDlgItemMessage
  1132.         (
  1133.             hDlgChildren,
  1134.             IDC_LISTBOX,
  1135.             LB_GETCOUNT,
  1136.             0,
  1137.             0L
  1138.         ))
  1139.     )
  1140.     {
  1141.         SetWindowText(hDlgChildren, "No children");
  1142.     }
  1143.     else
  1144.     {
  1145.         if(i == 1)
  1146.         {
  1147.             SetWindowText(hDlgChildren, "One child");
  1148.         }
  1149.         else
  1150.         {
  1151.             wsprintf(Text, "%d Children", i);
  1152.             SetWindowText(hDlgChildren, Text);
  1153.         }
  1154.     }
  1155.     if(GetParent(hWndTarget))
  1156.     {
  1157.         SendDlgItemMessage
  1158.         (
  1159.             hDlgChildren,
  1160.             IDC_LISTBOX,
  1161.             LB_ADDSTRING,
  1162.             0,
  1163.             (LONG) (LPSTR) "\"..\" (parent)"
  1164.         );
  1165.     }
  1166.     EnumProps(hWndTarget, lpEnumWindowPropsProc);
  1167.     if
  1168.     (
  1169.         !(i = (int) SendDlgItemMessage
  1170.         (
  1171.             hDlgProperties,
  1172.             IDC_LISTBOX,
  1173.             LB_GETCOUNT,
  1174.             0,
  1175.             0L
  1176.         ))
  1177.     )
  1178.     {
  1179.         SetWindowText(hDlgProperties, "No properties");
  1180.     }
  1181.     else
  1182.     {
  1183.         if(i == 1)
  1184.         {
  1185.             SetWindowText(hDlgProperties, "One property");
  1186.         }
  1187.         else
  1188.         {
  1189.             wsprintf(Text, "%d Properties", i);
  1190.             SetWindowText(hDlgProperties, Text);
  1191.         }
  1192.     }
  1193.  
  1194.     // Now, turn redrawing for both listbox windows back on, invalidating their
  1195.     // areas, and sending a WM_PAINT.
  1196.     SendDlgItemMessage(hDlgChildren, IDC_LISTBOX, WM_SETREDRAW, 1, 0L);
  1197.     SendDlgItemMessage(hDlgProperties, IDC_LISTBOX, WM_SETREDRAW, 1, 0L);
  1198.     InvalidateRect(GetDlgItem(hDlgChildren, IDC_LISTBOX), NULL, TRUE);
  1199.     InvalidateRect(GetDlgItem(hDlgProperties, IDC_LISTBOX), NULL, TRUE);
  1200.     UpdateWindow(GetDlgItem(hDlgChildren, IDC_LISTBOX));
  1201.     UpdateWindow(GetDlgItem(hDlgProperties, IDC_LISTBOX));
  1202.  
  1203.     // Update the Data window
  1204.     SendDlgItemMessage(hDlgExtraData, IDC_WNDLIST, WM_SETREDRAW, 0, 0L);
  1205.     SendDlgItemMessage(hDlgExtraData, IDC_CLSLIST, WM_SETREDRAW, 0, 0L);
  1206.     SendDlgItemMessage(hDlgExtraData, IDC_WNDLIST, LB_RESETCONTENT, 0, 0L);
  1207.     SendDlgItemMessage(hDlgExtraData, IDC_CLSLIST, LB_RESETCONTENT, 0, 0L);
  1208.     WndExtraData = GetClassWord(hWndTarget, GCW_CBWNDEXTRA);
  1209.     ClsExtraData = GetClassWord(hWndTarget, GCW_CBCLSEXTRA);
  1210.     if(ShowHex)
  1211.     {
  1212.         wsprintf
  1213.         (
  1214.             (LPSTR) Text,
  1215.             "Window = 0x%04x bytes",
  1216.             WndExtraData
  1217.         );
  1218.     }
  1219.     else
  1220.     {
  1221.         wsprintf
  1222.         (
  1223.             (LPSTR) Text,
  1224.             "Window = %d bytes",
  1225.             WndExtraData
  1226.         );
  1227.     }
  1228.     SetDlgItemText(hDlgExtraData, IDC_WNDTEXT, (LPSTR) Text);
  1229.     for(i = 0; i < (int) WndExtraData; i += 2)
  1230.     {
  1231.         BYTE Byte[5];
  1232.         if(ShowHex)
  1233.         {
  1234.             wsprintf(Byte, "0x%04x", GetWindowWord(hWndTarget, i));
  1235.         }
  1236.         else
  1237.         {
  1238.             wsprintf(Byte, "%d", GetWindowWord(hWndTarget, i));
  1239.         }
  1240.         SendDlgItemMessage
  1241.         (
  1242.             hDlgExtraData,
  1243.             IDC_WNDLIST,
  1244.             LB_ADDSTRING,
  1245.             0,
  1246.             (LONG) (LPSTR) Byte
  1247.         );
  1248.     }
  1249.  
  1250.     // Reset, and then fill the class bytes listbox
  1251.     if(ShowHex)
  1252.     {
  1253.         wsprintf
  1254.         (
  1255.             (LPSTR) Text,
  1256.             "Class = 0x%04x bytes",
  1257.             ClsExtraData
  1258.         );
  1259.     }
  1260.     else
  1261.     {
  1262.         wsprintf
  1263.         (
  1264.             (LPSTR) Text,
  1265.             "Class = %d bytes",
  1266.             ClsExtraData
  1267.         );
  1268.     }
  1269.     SetDlgItemText(hDlgExtraData, IDC_CLSTEXT, (LPSTR) Text);
  1270.     for(i = 0; i < (int) ClsExtraData; i += 2)
  1271.     {
  1272.         BYTE Byte[7];
  1273.         if(ShowHex)
  1274.         {
  1275.             wsprintf(Byte, "0x%04x", GetClassWord(hWndTarget, i));
  1276.         }
  1277.         else
  1278.         {
  1279.             wsprintf(Byte, "%d", GetClassWord(hWndTarget, i));
  1280.         }
  1281.         SendDlgItemMessage
  1282.         (
  1283.             hDlgExtraData,
  1284.             IDC_CLSLIST,
  1285.             LB_ADDSTRING,
  1286.             0,
  1287.             (LONG) (LPSTR) Byte
  1288.         );
  1289.     }
  1290.     SendDlgItemMessage(hDlgExtraData, IDC_CLSLIST, WM_SETREDRAW, 1, 0L);
  1291.     SendDlgItemMessage(hDlgExtraData, IDC_WNDLIST, WM_SETREDRAW, 1, 0L);
  1292.     InvalidateRect(GetDlgItem(hDlgExtraData, IDC_CLSLIST), NULL, TRUE);
  1293.     InvalidateRect(GetDlgItem(hDlgExtraData, IDC_WNDLIST), NULL, TRUE);
  1294.     UpdateWindow(GetDlgItem(hDlgExtraData, IDC_CLSLIST));
  1295.     UpdateWindow(GetDlgItem(hDlgExtraData, IDC_WNDLIST));
  1296.  
  1297.     // Update the Styles window
  1298.     SendDlgItemMessage(hDlgStyles, IDC_WNDLIST, WM_SETREDRAW, 0, 0L);
  1299.     SendDlgItemMessage(hDlgStyles, IDC_CLSLIST, WM_SETREDRAW, 0, 0L);
  1300.     SendDlgItemMessage(hDlgStyles, IDC_WNDLIST, LB_RESETCONTENT, 0, 0L);
  1301.     SendDlgItemMessage(hDlgStyles, IDC_CLSLIST, LB_RESETCONTENT, 0, 0L);
  1302.     WndStyle    = GetWindowLong(hWndTarget, GWL_STYLE);
  1303.     ClassStyle  = GetClassWord(hWndTarget, GCW_STYLE);
  1304.     if(ShowHex)
  1305.     {
  1306.         wsprintf
  1307.         (
  1308.             (LPSTR) Text,
  1309.             "Wnd Style = 0x%08lx",
  1310.             WndStyle
  1311.         );
  1312.     }
  1313.     else
  1314.     {
  1315.         wsprintf
  1316.         (
  1317.             (LPSTR) Text,
  1318.             "Wnd Style = %ld",
  1319.             WndStyle
  1320.         );
  1321.     }
  1322.     SetDlgItemText(hDlgStyles, IDC_WNDTEXT, (LPSTR) Text);
  1323.  
  1324.     // Check to see if the window is a popup. If so, don't throw in
  1325.     // WS_OVERLAPPED attribute.
  1326.     if(WndStyle & WndStyles[0].Style)
  1327.     {
  1328.         SendDlgItemMessage
  1329.         (
  1330.             hDlgStyles,
  1331.             IDC_WNDLIST,
  1332.             LB_ADDSTRING,
  1333.             0,
  1334.             (LONG) (LPSTR) WndStyles[1].Text
  1335.         );
  1336.     }
  1337.     else
  1338.     {
  1339.         if(WndStyle & WndStyles[1].Style)
  1340.         {
  1341.             SendDlgItemMessage
  1342.             (
  1343.                 hDlgStyles,
  1344.                 IDC_WNDLIST,
  1345.                 LB_ADDSTRING,
  1346.                 0,
  1347.                 (LONG) (LPSTR) WndStyles[0].Text
  1348.             );
  1349.         }
  1350.     }
  1351.     for(i = 2; i < NUMWNDSTYLES; ++i)
  1352.     {
  1353.         if(WndStyle & WndStyles[i].Style)
  1354.         {
  1355.             SendDlgItemMessage
  1356.             (
  1357.                 hDlgStyles,
  1358.                 IDC_WNDLIST,
  1359.                 LB_ADDSTRING,
  1360.                 0,
  1361.                 (LONG) (LPSTR) WndStyles[i].Text
  1362.             );
  1363.         }
  1364.     }
  1365.  
  1366.     // Reset, and then fill the class styles combo box
  1367.     if(ShowHex)
  1368.     {
  1369.         wsprintf
  1370.         (
  1371.             (LPSTR) Text,
  1372.             "Class Style = 0x%04x",
  1373.             ClassStyle
  1374.         );
  1375.     }
  1376.     else
  1377.     {
  1378.         wsprintf
  1379.         (
  1380.             (LPSTR) Text,
  1381.             "Class Style = %d",
  1382.             ClassStyle
  1383.         );
  1384.     }
  1385.     SetDlgItemText(hDlgStyles, IDC_CLSTEXT, (LPSTR) Text);
  1386.     for(i = 0; i < NUMCLASSSTYLES; ++i)
  1387.     {
  1388.         if(ClassStyle & ClassStyles[i].Style)
  1389.         {
  1390.             SendDlgItemMessage
  1391.             (
  1392.                 hDlgStyles,
  1393.                 IDC_CLSLIST,
  1394.                 LB_ADDSTRING,
  1395.                 0,
  1396.                 (LONG) (LPSTR) ClassStyles[i].Text
  1397.             );
  1398.         }
  1399.     }
  1400.  
  1401.     // Turn off outline of target window
  1402.     OutlineWindow(hWndTarget);
  1403.  
  1404.     // Turn redrawing back on and repaint all listboxes
  1405.     SendDlgItemMessage(hDlgStyles, IDC_WNDLIST, WM_SETREDRAW, 1, 0L);
  1406.     SendDlgItemMessage(hDlgStyles, IDC_CLSLIST, WM_SETREDRAW, 1, 0L);
  1407.     InvalidateRect(GetDlgItem(hDlgStyles, IDC_WNDLIST), NULL, TRUE);
  1408.     InvalidateRect(GetDlgItem(hDlgStyles, IDC_CLSLIST), NULL, TRUE);
  1409.     UpdateWindow(GetDlgItem(hDlgStyles, IDC_WNDLIST));
  1410.     UpdateWindow(GetDlgItem(hDlgStyles, IDC_CLSLIST));
  1411. }
  1412.  
  1413. /*****************************************************************************
  1414.     FUNCTION: EnumWindowPropsProc
  1415.     PURPOSE : Enumerates properties for window under mouse
  1416. *****************************************************************************/
  1417. int FAR PASCAL EnumWindowPropsProc(HWND hWnd, LPSTR lpString, HANDLE hData)
  1418. {
  1419.     // Check the passed property name to see if it's a string or an atom
  1420.     if(HIWORD(lpString))
  1421.     {
  1422.         if(ShowHex)
  1423.         {
  1424.             wsprintf(Text, "%s\t= 0x%04x", (LPSTR) lpString, hData);
  1425.         }
  1426.         else
  1427.         {
  1428.             wsprintf(Text, "%s\t= %d", (LPSTR) lpString, hData);
  1429.         }
  1430.     }
  1431.     else
  1432.     {
  1433.         if(ShowHex)
  1434.         {
  1435.             wsprintf(Text, "0x%04x, 0x%04x", LOWORD((DWORD) lpString), hData);
  1436.         }
  1437.         else
  1438.         {
  1439.             wsprintf(Text, "%d, %d", LOWORD((DWORD) lpString), hData);
  1440.         }
  1441.     }
  1442.     SendDlgItemMessage
  1443.     (
  1444.         hDlgProperties,
  1445.         IDC_LISTBOX,
  1446.         LB_ADDSTRING,
  1447.         0,
  1448.         (LONG) (LPSTR) Text
  1449.     );
  1450.     return(1);
  1451. }
  1452.  
  1453. /*****************************************************************************
  1454.     FUNCTION: DrawIcons
  1455.     PURPOSE : Draws the target and parent class icons
  1456. *****************************************************************************/
  1457. VOID PASCAL DrawIcons(VOID)
  1458. {
  1459.     HWND    hWndParent;
  1460.     HDC     hDC;
  1461.     HFONT   hFont;
  1462.     HICON   hIcon;
  1463.     BYTE    ClassName[30];
  1464.     if(hWndTarget == NULL)
  1465.     {
  1466.         return;
  1467.     }
  1468.  
  1469.     // Setup small prop helv font for icon titles
  1470.     hFont = CreateFont
  1471.     (
  1472.         12, 0,
  1473.         0, 0,
  1474.         FW_NORMAL,
  1475.         FALSE,
  1476.         FALSE,
  1477.         FALSE,
  1478.         ANSI_CHARSET,
  1479.         OUT_DEFAULT_PRECIS,
  1480.         CLIP_DEFAULT_PRECIS,
  1481.         DEFAULT_QUALITY,
  1482.         VARIABLE_PITCH | FF_SWISS,
  1483.         "Helv"
  1484.     );
  1485.  
  1486.     // Get window class name & draw icon
  1487.     if(!GetClassName(hWndTarget, (LPSTR) ClassName, sizeof(ClassName)))
  1488.     {
  1489.         ClassName[0] = '\0';
  1490.     }
  1491.     if((hIcon = GetClassWord(hWndTarget, GCW_HICON)) == NULL)
  1492.     {
  1493.         if(!lstrcmpi((LPSTR) ClassName, "listbox"))
  1494.         {
  1495.             hIcon = LoadIcon(hInstPropView, "listbox");
  1496.         }
  1497.         else
  1498.         {
  1499.             if(!lstrcmpi((LPSTR) ClassName, "combobox"))
  1500.             {
  1501.                 hIcon = LoadIcon(hInstPropView, "combobox");
  1502.             }
  1503.             else
  1504.             {
  1505.                 if(!lstrcmpi((LPSTR) ClassName, "button"))
  1506.                 {
  1507.                     hIcon = LoadIcon(hInstPropView, "button");
  1508.                 }
  1509.                 else
  1510.                 {
  1511.                     if(!lstrcmpi((LPSTR) ClassName, "edit") ||
  1512.                         !lstrcmpi((LPSTR) ClassName, "static"))
  1513.                     {
  1514.                         hIcon = LoadIcon(hInstPropView, "editcontrol");
  1515.                     }
  1516.                 }
  1517.             }
  1518.         }
  1519.     }
  1520.  
  1521.     // Get DC, draw icon, and release DC
  1522.     hDC = GetDC(GetDlgItem(hDlgPropView, IDC_HWNDICON));
  1523.     if((hIcon == NULL) && IsIconic(hWndTarget) && IsWindowVisible(hWndTarget))
  1524.     {
  1525.         HDC hDCTarget = GetWindowDC(hWndTarget);
  1526.         BitBlt(hDC, 0, 0, 36, 36, hDCTarget, 0, 0, SRCCOPY);
  1527.         ReleaseDC(hWndTarget, hDCTarget);
  1528.     }
  1529.     else
  1530.     {
  1531.         BitBlt(hDC, 0, 0, 36, 36, hDC, 0, 0, WHITENESS);
  1532.         DrawIcon(hDC, 0, 0, hIcon);
  1533.     }
  1534.     ReleaseDC(GetDlgItem(hDlgPropView, IDC_HWNDICON), hDC);
  1535.     if((hWndParent = GetParent(hWndTarget)) != NULL)
  1536.     {
  1537.         HICON hIcon;
  1538.         // Get DC, draw icon, and release DC
  1539.         hDC = GetDC(GetDlgItem(hDlgPropView, IDC_PARENTICON));
  1540.         if
  1541.         (
  1542.             ((hIcon = GetClassWord(hWndParent, GCW_HICON)) == NULL) &&
  1543.             IsIconic(hWndParent) && IsWindowVisible(hWndTarget)
  1544.         )
  1545.         {
  1546.             HDC hDCTarget = GetWindowDC(hWndParent);
  1547.             BitBlt(hDC, 0, 0, 36, 36, hDCTarget, 0, 0, SRCCOPY);
  1548.             ReleaseDC(hWndParent, hDCTarget);
  1549.         }
  1550.         else
  1551.         {
  1552.             BitBlt(hDC, 0, 0, 36, 36, hDC, 0, 0, WHITENESS);
  1553.             DrawIcon(hDC, 0, 0, hIcon);
  1554.         }
  1555.         ReleaseDC(GetDlgItem(hDlgPropView, IDC_PARENTICON), hDC);
  1556.     }
  1557.     else
  1558.     {
  1559.         // Get DC, draw icon, and release DC
  1560.         hDC = GetDC(GetDlgItem(hDlgPropView, IDC_PARENTICON));
  1561.         BitBlt(hDC, 0, 0, 36, 36, hDC, 0, 0, WHITENESS);
  1562.         ReleaseDC(GetDlgItem(hDlgPropView, IDC_PARENTICON), hDC);
  1563.     }
  1564.  
  1565.     // Do usual cleanup
  1566.     DeleteObject(hFont);
  1567. }
  1568.  
  1569. /*****************************************************************************
  1570.     FUNCTION: EnumChildrenProc
  1571.     PURPOSE : Enumerates children of window under mouse
  1572. *****************************************************************************/
  1573. int FAR PASCAL EnumChildrenProc(HWND hWnd, DWORD lParam)
  1574. {
  1575.     BYTE Text[100];
  1576.     BYTE Caption[100];
  1577.     BYTE ClassName[30];
  1578.  
  1579.     // Get the child window's caption and class name
  1580.     GetWindowText(hWnd, (LPSTR) Caption, sizeof(Caption));
  1581.     GetClassName(hWnd, (LPSTR) ClassName, sizeof(ClassName));
  1582.  
  1583.     // Format and add the entry to the child list box
  1584.     if(Caption[0] != '\0')
  1585.     {
  1586.         if(ShowHex)
  1587.         {
  1588.             wsprintf
  1589.             (
  1590.                 (LPSTR) Text,
  1591.                 "%s\t0x%04x\t0x%04x\t\"%s\"",
  1592.                 (LPSTR) ClassName,
  1593.                 GetDlgCtrlID(hWnd),
  1594.                 hWnd,
  1595.                 (LPSTR) Caption
  1596.             );
  1597.         }
  1598.         else
  1599.         {
  1600.             wsprintf
  1601.             (
  1602.                 (LPSTR) Text,
  1603.                 "%s\t%d\t%d\t\"%s\"",
  1604.                 (LPSTR) ClassName,
  1605.                 GetDlgCtrlID(hWnd),
  1606.                 hWnd,
  1607.                 (LPSTR) Caption
  1608.             );
  1609.         }
  1610.     }
  1611.     else
  1612.     {
  1613.         if(ShowHex)
  1614.         {
  1615.             wsprintf
  1616.             (
  1617.                 (LPSTR) Text,
  1618.                 "%s\t0x%04x\t0x%04x",
  1619.                 (LPSTR) ClassName,
  1620.                 GetDlgCtrlID(hWnd),
  1621.                 hWnd
  1622.             );
  1623.         }
  1624.         else
  1625.         {
  1626.             wsprintf
  1627.             (
  1628.                 (LPSTR) Text,
  1629.                 "%s\t%d\t%d",
  1630.                 (LPSTR) ClassName,
  1631.                 GetDlgCtrlID(hWnd),
  1632.                 hWnd
  1633.             );
  1634.         }
  1635.     }
  1636.     SendDlgItemMessage
  1637.     (
  1638.         hDlgChildren,
  1639.         IDC_LISTBOX,
  1640.         LB_ADDSTRING,
  1641.         0,
  1642.         (LONG) (LPSTR) Text
  1643.     );
  1644.     return(1);
  1645. }
  1646.  
  1647. /*****************************************************************************
  1648.     FUNCTION: About
  1649.     PURPOSE : Processes messages for About box
  1650. *****************************************************************************/
  1651. BOOL FAR PASCAL About(HWND hWnd, unsigned wMsg, WORD wParam, LONG lParam)
  1652. {
  1653.     switch(wMsg)
  1654.     {
  1655.         case WM_INITDIALOG :
  1656.             return(TRUE);
  1657.         case WM_COMMAND    :
  1658.             if(wParam == IDOK || wParam == IDCANCEL)
  1659.             {
  1660.                 EndDialog(hWnd, TRUE);
  1661.                 return(TRUE);
  1662.             }
  1663.             break;
  1664.         default            :
  1665.             break;
  1666.     }
  1667.     return(FALSE);
  1668. }
  1669.  
  1670. /*****************************************************************************
  1671.     FUNCTION: OutlineWindow
  1672.     PURPOSE : Outlines window with a rectangle
  1673. *****************************************************************************/
  1674. VOID PASCAL OutlineWindow(HWND hWnd)
  1675. {
  1676.     RECT    Rect;
  1677.     HDC     hDC;
  1678.     HPEN    hPen;
  1679.     HPEN    hPenOld;
  1680.     HANDLE  hBrush;
  1681.     HANDLE  hBrushOld;
  1682.     int     OldROP2Mode;
  1683.  
  1684.     // Check for valid window handle and pen thickness
  1685.     if(!IsWindow(hWnd))
  1686.     {
  1687.         return;
  1688.     }
  1689.  
  1690.     // Set up parms to draw rectangle
  1691.     hBrush  = GetStockObject(NULL_BRUSH);
  1692.     hPen    = CreatePen(PS_SOLID, 6, RGB(0, 0, 0));
  1693.  
  1694.     // Get DC for window and it's dimensions
  1695.     hDC = GetWindowDC(hWnd);
  1696.     GetWindowRect(hWnd, (LPRECT) &Rect);
  1697.  
  1698.     // Set drawing mode parameters
  1699.     hBrushOld   = SelectObject(hDC, hBrush);
  1700.     hPenOld     = SelectObject(hDC, hPen);
  1701.     OldROP2Mode = SetROP2(hDC, R2_NOT);
  1702.  
  1703.     // Draw the rectangle and release the DC
  1704.     Rectangle(hDC, 0, 0, Rect.right - Rect.left, Rect.bottom - Rect.top);
  1705.  
  1706.     // Be a good boy and reset the old context attributes
  1707.     SelectObject(hDC, hBrushOld);
  1708.     SelectObject(hDC, hPenOld);
  1709.     DeleteObject(hPen);
  1710.     SetROP2(hDC, OldROP2Mode);
  1711.  
  1712.     ReleaseDC(hWnd, hDC);
  1713. }
  1714.  
  1715.